import { Result } from "../result";
import { Theme, ThemeOpts } from "../theme";
import { mockTheme, MockThemeKeyType } from "./mock";
import { Color } from "../meta/color";
type AnyObject = { [key in any]: any };
export class CssTheme implements Theme {
  // 存储css变量
  private variables: Map<string, string>;

  // 将配置json存储到map中
  constructor(opts?: ThemeOpts) {
    this.variables = new Map([]);
    if (!opts) return;
    const _this = this;
    const START_SYMBOL = "--";
    const MIDDLE_SYMBOL = "-";
    // 递归进行key的拼接
    function convert(
      themeObj: AnyObject,
      mockObj: AnyObject,
      split: string = ""
    ) {
      let str = split ? split : MIDDLE_SYMBOL + split;
      for (const key in themeObj) {
        let convertStr = str + MIDDLE_SYMBOL + key;
        // 判断是否存在key
        if (Object.keys(mockObj).includes(key)) {
          // 如果是对象
          if (typeof mockObj[key] == "object") {
            convert(themeObj[key], mockObj[key], convertStr);
          } else {
            // 如果得到的是Class
            if (mockObj[key] && typeof mockObj[key] == "function") {
              // 获取mock中的类,调用方法检测是否转换成功
              const themeInstance = new mockObj[key](themeObj[key]);
              if (!themeInstance.cssValueError()) {
                // 成功则进行存储
                if (mockObj[key] == Color) {
                  for (let i = 1; i <= 6; i++) {
                    _this.variables.set(
                      convertStr + i,
                      themeInstance.getLevel(i) || ""
                    );
                  }
                }
                _this.variables.set(convertStr, themeInstance.cssValue() || "");
              } else {
                console.warn(themeInstance.cssValueError());
              }
            } else {
              // 得到的值是undefined
              _this.variables.set(convertStr, themeObj[key] + "px" || "");
            }
          }
        }
      }
    }

    for (const key in opts) {
      const mock = this.getMockTheme(key as MockThemeKeyType);
      if (mock) {
        convert((<any>opts)[key], <any>mock, START_SYMBOL + key);
      }
    }
  }
  // 获取模拟的Theme
  private getMockTheme(themeName: MockThemeKeyType): string | undefined {
    let str = "";
    for (const k in mockTheme) {
      if (themeName == mockTheme[k].themeName) {
        return (str = mockTheme[k]);
      }
    }
  }
  // 返回不能改变的一个map对象
  variableMap(): Map<string, string> {
    this.variables.set = function () {
      throw new Error("variableMap:该map的属性只可读");
    };
    return this.variables;
  }
  // 将所有css转换为 split 分隔
  variableString(split: string = ";\n"): string {
    let cssStyle: string = "";
    this.variables.forEach((value, key) => {
      let templateCss = "" + key + ":" + value + split;
      cssStyle += templateCss;
    });
    return `:root{${cssStyle}}`;
  }
  // 设置css
  setVariable(name: string, value: string): Result<undefined> {
    this.variables.set(name, value);
    return Result.succ();
  }
  // 获取css
  getVariable(name: string): string {
    const cssVal = this.variables.get(name);
    return cssVal || "";
  }
}
